package com.medsoft.drpcp;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.medsoft.base.utils.JsonUtils;
import com.medsoft.drpcp.meta.DrpcpHead;
import com.medsoft.drpcp.meta.DrpcpHeadConstant;

public class DrpcpRouter {
	static final Logger logger = LoggerFactory.getLogger(DrpcpRouter.class);
	public static Map<String,BlockingQueue<String>> drpcpMultiplex = new HashMap<String,BlockingQueue<String>>();
	
	public static String call(String serviceId, String drpcpMsgId,String crc32,String args,ServiceDefinition serviceDef) throws Exception {
		//获取定义获取移到外面，这样动态和静态调用本身的逻辑就不变 20160805 changed
		//ServiceDefinition serviceDef = ServiceDefinitionContainer.getService(serviceId);
		//调用drpcp服务
		BlockingQueue<String> retQueue = new LinkedBlockingQueue<String>(1);
		drpcpMultiplex.put(drpcpMsgId, retQueue);
		ChannelFuture future = callDrpcpService(GlobalConfig.getRandomMember(serviceDef.getNodeName()),serviceId + drpcpMsgId + crc32 + args);
		if (future == null) {
			Object ret = new DrpcpHead();
			((DrpcpHead) ret).setDrpcpMsgId(drpcpMsgId);
			((DrpcpHead) ret).setDrpcpErrorNo(DrpcpHeadConstant.ERROR_NO_DISCONNECT_FROM_SERVER);
			((DrpcpHead) ret).setDrpcpErrorInfo(DrpcpHeadConstant.ERROR_INFO_DISCONNECT_FROM_SERVER);
			return JsonUtils.toJson(ret);
		}
		String retJsonStr = retQueue.poll(serviceDef.getTimeout(), TimeUnit.SECONDS);
		drpcpMultiplex.remove(drpcpMsgId);
		logger.debug("drpcp server return: " + (retJsonStr == null ? "request timeout! " : retJsonStr));
		return retJsonStr;
	}
	
	public static ChannelFuture callDrpcpService(Channel channel,String drpcpMsg) {  
        if(channel!=null){  
            try {
				return channel.writeAndFlush(drpcpMsg).sync();
			} catch (Exception e) {
				logger.error("timeout occured during channel send msg.",e);
			}
        }else{
        	logger.error("send msg failed, channel is disconnected or not connect.");
        }
        return null;
    }
}
